#pragma once
#include <nlohmann/json.hpp>
#include "protocol.h"
#include <cstring>
#include <vector>
#include <string>
#include <optional>

// Windows 字节序转换
#ifdef _WIN32
    #include <winsock2.h>
#else
    #include <arpa/inet.h>
#endif

using json = nlohmann::json;

class MessageCodec
{
public:
    // ==================== 编码方法 ====================
    
    // 通用编码：消息格式 [长度(4字节)] + [类型(2字节)] + [JSON内容]
    static std::vector<uint8_t> encode(MsgType type, const std::string& jsonBody);
    
    // 便捷编码方法
    static std::vector<uint8_t> encode(const LoginRequest& msg);
    static std::vector<uint8_t> encode(const LoginResponse& msg);
    static std::vector<uint8_t> encode(const TextMessage& msg);
    static std::vector<uint8_t> encode(const HeartBeat& msg);
    static std::vector<uint8_t> encode(const GetFriendListRequest& msg);
    static std::vector<uint8_t> encode(const GetFriendListResponse& msg);
    static std::vector<uint8_t> encode(const FileDownloadRequest& msg);
    static std::vector<uint8_t> encode(const FileDownloadResponse& msg);
    static std::vector<uint8_t> encode(const FileDownloadProgress& msg);
    static std::vector<uint8_t> encode(const FileUploadRequest& msg);
    static std::vector<uint8_t> encode(const FileUploadData& msg);
    static std::vector<uint8_t> encode(const FileUploadResponse& msg);
    static std::vector<uint8_t> encode(const FileGetRequest& msg);
    static std::vector<uint8_t> encode(const FileGetResponse& msg);
    static std::vector<uint8_t> encode(const FriendStatusNotify& msg);
    
    // ==================== 解码方法 ====================
    
    // 解析消息头（前6字节）
    static std::optional<MessageHeader> parseHeader(const uint8_t* data, size_t len);
    
    // 通用解码：字节流 → (消息类型, JSON字符串)
    static std::pair<MsgType, std::string> decode(const std::vector<uint8_t>& data);
    
    // ==================== JSON 序列化 ====================
    
    // 结构体 → JSON 字符串
    static std::string toJson(const LoginRequest& msg);
    static std::string toJson(const LoginResponse& msg);
    static std::string toJson(const TextMessage& msg);
    static std::string toJson(const HeartBeat& msg);
    static std::string toJson(const GetFriendListRequest& msg);
    static std::string toJson(const GetFriendListResponse& msg);
    static std::string toJson(const FriendInfo& msg);
    static std::string toJson(const FileDownloadRequest& msg);
    static std::string toJson(const FileDownloadResponse& msg);
    static std::string toJson(const FileDownloadProgress& msg);
    static std::string toJson(const FileUploadRequest& msg);
    static std::string toJson(const FileUploadData& msg);
    static std::string toJson(const FileUploadResponse& msg);
    static std::string toJson(const FileGetRequest& msg);
    static std::string toJson(const FileGetResponse& msg);
    static std::string toJson(const FriendStatusNotify& msg);
    
    // ==================== JSON 反序列化 ====================
    
    // JSON 字符串 → 结构体
    static std::optional<LoginRequest> loginRequestFromJson(const std::string& jsonStr);
    static std::optional<LoginResponse> loginResponseFromJson(const std::string& jsonStr);
    static std::optional<TextMessage> textMessageFromJson(const std::string& jsonStr);
    static std::optional<HeartBeat> heartBeatFromJson(const std::string& jsonStr);
    static std::optional<GetFriendListRequest> getFriendListRequestFromJson(const std::string& jsonStr);
    static std::optional<GetFriendListResponse> getFriendListResponseFromJson(const std::string& jsonStr);
    static std::optional<FriendInfo> friendInfoFromJson(const json& j);
    static std::optional<FileDownloadRequest> fileDownloadRequestFromJson(const std::string& jsonStr);
    static std::optional<FileDownloadResponse> fileDownloadResponseFromJson(const std::string& jsonStr);
    static std::optional<FileDownloadProgress> fileDownloadProgressFromJson(const std::string& jsonStr);
    static std::optional<FileUploadRequest> fileUploadRequestFromJson(const std::string& jsonStr);
    static std::optional<FileUploadData> fileUploadDataFromJson(const std::string& jsonStr);
    static std::optional<FileUploadResponse> fileUploadResponseFromJson(const std::string& jsonStr);
    static std::optional<FileGetRequest> fileGetRequestFromJson(const std::string& jsonStr);
    static std::optional<FileGetResponse> fileGetResponseFromJson(const std::string& jsonStr);

private:
    // ==================== 辅助方法 ====================
    
    // 读写字节（内部已处理字节序转换）
    static uint32_t readUint32(const uint8_t* data);
    static uint16_t readUint16(const uint8_t* data);
    static void writeUint32(std::vector<uint8_t>& buf, uint32_t value);
    static void writeUint16(std::vector<uint8_t>& buf, uint16_t value);
};
